<script lang='ts' setup>

import { onMounted, ref, watch } from 'vue';
import * as qiniu from 'qiniu-js';
import { Message } from "@arco-design/web-vue";
import { AssetInfo } from '@/models/asset';
import { appContext } from '@/models/app.context';
import { assetService } from '@/services/asset.service';
import { FormatDate, base64toFile, getImageEl, getUuid } from '@/utils/common.methods';
import { ProportionalCompression } from '@/utils/image.method';
import { appRef } from '@/models/app.ref';
import { resolve } from 'dns';

interface UploadPropsInfo {
  files?: File[];
  assets?: AssetInfo[];
  owner?: string;
  accept?: string;
  multiple?: boolean;
  limit?: number;
  /** 上传成功回调 */
  success?: (assets: AssetInfo[]) => void;
  /** 上传错误回调 */
  fail?: (msg: string) => void;
  /** 完成回调，成功错误都会返回 */
  complete?: () => void;
}


const props = defineProps<UploadPropsInfo>()
const emits = defineEmits(['update:files', 'uploadComplete']);
defineExpose({ onUpload })

// watch(() => props.files, () => {
//   files.value = props.files;
// })


onMounted(async () => {
  if (props?.files?.length) {
    try {
      await onUpload(props.files).then((res) => {
        props.success(res)
      })
    } catch (error) {
      props.fail && props?.fail(error)
    }
    props?.complete && props?.complete();
  }
})



const loading = ref(false);


/** 上传 */
async function onUpload(files: any[]): Promise<AssetInfo[]> {
  loading.value = true;
  Message.loading({ content: '上传中', duration: 0 })
  const smallMax = 512;  // 最长边限制
  const snapshotMax = 1024; // 最长边限制
  const assets: AssetInfo[] = [];
  return new Promise<AssetInfo[]>(resolve => {
    files?.map(async file => {
      const temp = {} as any;
      temp.url = file;
      temp.type = temp.format = file.type;
      temp.name = file.name;
      if (file.type?.includes("image/")) {
        const tempUrl = URL.createObjectURL(file)
        const img = await getImageEl(tempUrl);
        if (img?.width) {
          const { width, height } = img;
          // img.setAttribute("crossOrigin", "Anonymous"); // 设置crossOrigin属性为Anonymous
          // 将图像转为封面图和快照，最长边限制为  smallMax 和 snapshotMax
          temp.small = await ProportionalCompression(img, width, height, smallMax);
          temp.snapshot = await ProportionalCompression(img, width, height, snapshotMax);
        }
      }
      const asset = await Uploading(temp);
      assets.push(asset);
      if (assets?.length === files?.length) {
        loading.value = false;
        Message.clear();
        Message.success("上传成功");
        emits('uploadComplete', files);
        resolve(assets);
      }
    })
  })
}

function Uploading(file: any): Promise<AssetInfo> {
  return new Promise(async (resolve) => {
    loading.value = true;
    const asset = await uploadAsset(await upload(file?.url || file), file, (await upload(file?.small))?.key, (await upload(file?.snapshot))?.key);
    resolve(asset);
  });
}

async function upload(file: any): Promise<any> {
  if (!file) return await new Promise((resolve) => resolve(undefined));
  console.log('upload', file);
  const { token, region, bucket, domain } = appContext.global.assetToken;
  const config = { useCdnDomain: !!domain, region, bucket };
  const putExtra = { fname: file?.name || getUuid(), params: {}, mimeType: null, };
  const suffix = file?.name?.slice(file?.name.lastIndexOf(".")).toLowerCase();
  return await new Promise((resolve) => qiniu.upload(file?.url || file, getUuid() + suffix, token, putExtra, config).subscribe({ complete(res) { resolve(res) } }));
}


async function uploadAsset(result: any, file?: File, small?: string, snapshot?: string): Promise<AssetInfo> {
  if (!result?.key) return;
  const owner = props.owner || appRef.user?.data?.uid;
  const { hash, key, format, size, md5, img } = result;
  return await assetService.add(file.name, format || file.type, md5, size, hash, owner, key, small || key, snapshot || key, img?.width || 0, img?.height || 0,);
} 
</script>
<template>
  <div>
    <slot> </slot>
  </div>
</template>
<style lang='scss' scoped>
.h-upload {
  .box {
    height: 120px;
    border-radius: 4px;
    background: #F6F6F6;
    justify-content: center;
  }
}
</style>